import requests
from django.conf import settings
from rest_framework_simplejwt.tokens import RefreshToken

from .models import User, Technician


class UserService:
    """用户业务逻辑服务类"""

    @staticmethod
    def wechat_login(code, nickname=None, avatar=None, encrypted_data=None, iv=None):
        """微信登录"""
        # 使用环境变量中的小程序AppID和AppSecret
        appid = settings.WECHAT_APP_ID
        secret = settings.WECHAT_APP_SECRET

        # 如果是测试code，直接返回测试数据
        if code == "test_code":
            openid = "test_openid"
            session_key = "test_session_key"
        else:
            # 调用微信接口获取openid和session_key
            url = f'https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code'
            response = requests.get(url)
            result = response.json()

            if 'errcode' in result:
                raise ValueError('微信登录失败')

            openid = result['openid']
            session_key = result.get('session_key')

        # 获取或创建用户
        user, created = User.objects.get_or_create(
            openid=openid,
            defaults={
                'username': openid,
                'role': 'customer'  # 默认角色为顾客
            }
        )

        # 更新用户信息
        if nickname:
            user.username = nickname
            user.save()

        if avatar:
            user.avatar = avatar
            user.save()

        # 如果提供了手机号加密数据，解密并保存
        if encrypted_data and iv and session_key:
            try:
                from wechatpy.crypto import WeChatCrypto
                from wechatpy.exceptions import WeChatClientException
                import json

                crypto = WeChatCrypto(appid, session_key, appid)
                decrypted_data = crypto.decrypt_message(encrypted_data, iv, appid)
                # 解析解密后的数据
                phone_info = json.loads(decrypted_data)
                phone_number = phone_info.get('phoneNumber', '')

                # 更新用户手机号
                if phone_number:
                    user.phone = phone_number
                    user.save()
            except WeChatClientException as e:
                # 解密失败，记录日志但不影响登录流程
                print(f"手机号解密失败: {e}")
            except Exception as e:
                # 其他异常，记录日志但不影响登录流程
                print(f"处理手机号时发生错误: {e}")

        # 生成JWT token
        refresh = RefreshToken.for_user(user)

        return {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
            'user': {
                'id': user.id,
                'username': user.username,
                'openid': user.openid,
                'role': user.role,
                'phone': user.phone,
                'avatar': user.avatar.url if hasattr(user.avatar, 'url') else user.avatar if user.avatar else None
            }
        }

    @staticmethod
    def technician_certification(user, data):
        """技师认证申请"""
        # 检查是否已存在认证申请
        if hasattr(user, 'technician_profile'):
            raise ValueError('您已提交过认证申请')

        # 创建技师认证记录
        technician = Technician.objects.create(
            user=user,
            real_name=data['real_name'],
            id_card=data['id_card'],
            service_area=data['service_area'],
            experience=data['experience'],
            id_card_front=data.get('id_card_front'),
            id_card_back=data.get('id_card_back'),
            certification=data.get('certification')
        )

        return {
            'message': '认证申请已提交，等待审核',
            'id': technician.id
        }

    @staticmethod
    def switch_role(user, new_role):
        """切换用户角色"""
        if new_role not in ['customer', 'technician', 'admin']:
            raise ValueError('无效的角色')

        # 检查用户是否有权限切换到该角色
        if new_role == 'technician':
            # 检查是否是认证技师
            try:
                technician = user.technician_profile
                if not technician.is_verified:
                    raise PermissionError('技师未认证')
            except Technician.DoesNotExist:
                raise PermissionError('您不是认证技师')

        # 更新用户角色
        user.role = new_role
        user.save()

        return {
            'message': '角色切换成功',
            'role': user.role
        }
